#include "DB.h"
#include "DBPageManager.h"
#include "DBIndexManager.h"
#include "DBError.h"
#include <Windows.h>
#include <process.h>
#include <fcntl.h>
#include <io.h>
#include <sys\types.h> 
#include <sys\stat.h>
#include <stdlib.h>

/*
   int updateByTable(char* filename, int pageid, int offset, char* colName, colValue* newValue)
   {
   return 0;
   }

   int updateByFile(int fileid, int pageid, int offset, char* colName, colValue* newValue)
   {
   return 0;
   }
   */

int update(char* targetTable, whereRet* ret, char* colNames[], char* newValue[], int colNum)
{
    int i;
    int k;
    int fileid;
    int pageid;
    int rowid;
    int error;
    int colCount;
    int recordSize = 0;
    // maybe of no use
    unsigned long recordCount;

    char* tableName = malloc(100);
    char* fileName = malloc(100);
    char* dataBuf;
    DB_PAGE* buf;
    col* colDef = malloc(sizeof(col));
    short* dirty = malloc(sizeof(short) * colNum);
    // int short arr
    for (i = 0; i < colNum; i++)
    {
        *(dirty + i) = 1;
    }

    whereLoc* location;

    while (ret != NULL)
    {
        location = ret->locations;

        strcpy(tableName, location->tableName);
        strcpy(fileName, location->tableName);
        strcat(fileName, ".dbf");

        fileid = location->fileid;
        pageid = location->pageid;
        rowid = location->rowid;

        FILE* fp;
        fp = fopen(fileName, "rb+");
        if (fp == NULL)
        {
            printf("can not find file.\n");
            return -1;
        }

        fread(&recordCount, sizeof(unsigned long), 1, fp);
        fread(&colCount, sizeof(int), 1, fp);

        int vcharNumber = 0;
        for (i = 0; i < colCount; i++)
        {
            fread(colDef, sizeof(col), 1, fp);
            if (colDef->type == DATA_VCHAR)
            {
                vcharNumber = vcharNumber + 1;
            }
            recordSize = recordSize + colDef->size;
        }
        recordSize = recordSize + sizeof(unsigned long) + vcharNumber * sizeof(int) + colCount * sizeof(char);
        fseek(fp, sizeof(unsigned long) + sizeof(int), 0);

        fileid = DBFileIsOpen(tableName);
        if (fileid == -1)
        {
            fileid = DBOpenFile(tableName);
            if (fileid < 0)
            {
                printf("error in DBFileOpen!\n");
                DBPrintError(fileid);
                return -1;
            }
        } 

        if ( (error = DBGetPage(fileid, pageid, &buf)) != DB_OK)
        {
            DBPrintError(error);
            return -1;
        }

        DBPageUsed(fileid, pageid);
        dataBuf =  buf->pgdata;
        dataBuf = dataBuf + recordSize * rowid;
        dataBuf = dataBuf + sizeof(unsigned long);

        for (i = 0; i < colCount; i++)
        {
            fread(colDef, sizeof(col), 1, fp);

            for (k = 0; k < colNum; k++)
            {
                if (*(dirty + k) == 1 && strcmp(colDef->name, colNames[k]) == 0)
                {
                    // TODO
                    if (colDef->type == DATA_INT)
                    {                
                        if (newValue[k] == NULL)
                        {
                            char nullBit = 0;
                            memcpy(dataBuf, &nullBit, sizeof(char));
                        }
                        else
                        {
                            char nullBit = 1;
                            memcpy(dataBuf, &nullBit, sizeof(char));
                            int newNum = 0;
                            newNum = atoi(newValue[k]);
                            memcpy(dataBuf + sizeof(char), &newNum, sizeof(int));
                        }        
                    }
                    else if (colDef->type == DATA_CHAR)
                    {
                        if (newValue[k] == NULL)
                        {
                            char nullBit = 0;
                            memcpy(dataBuf, &nullBit, sizeof(char));   
                        }
                        else
                        {
                            char nullBit = 1;
                            memcpy(dataBuf, &nullBit, sizeof(char));
                            memcpy(dataBuf + sizeof(char), newValue[k], colDef->size);
                        }
                    }
                    else if (colDef->type == DATA_VCHAR)
                    {
                        if (newValue[k] == NULL)
                        {
                            char nullBit = 0;
                            memcpy(dataBuf, &nullBit, sizeof(char));
                            int newLen = 0;
                            memcpy(dataBuf + sizeof(char), &newLen, sizeof(int));
                        }
                        else
                        {
                            int newLen = 0;
                            char nullBit = 1;
                            memcpy(dataBuf, &nullBit, sizeof(char));
                            newLen = strlen(newValue[k]);
                            memcpy(dataBuf + sizeof(char), &newLen, sizeof(int));
                            memcpy(dataBuf + sizeof(char) + sizeof(int), newValue[k], colDef->size);    
                        }
                    }
                    *(dirty + k) = 0; 
                    break;
                }
            }

            if (colDef->type == DATA_INT)
            {
                dataBuf = dataBuf + sizeof(char) + sizeof(int);                
            }
            else if (colDef->type == DATA_CHAR)
            {
                dataBuf = dataBuf + sizeof(char) + colDef->size;
            }
            else if (colDef->type == DATA_VCHAR)
            {
                dataBuf = dataBuf + sizeof(char) + colDef->size + sizeof(int);
            }        
        }

        DBPageRelease(fileid, pageid, TRUE);
        DBDisposePage(fileid, pageid);

        fclose(fp);

        if (location->nextLoc != NULL)
        {
            //TODO
        }

        ret = ret->nextRet;

    }

    free(tableName);
    free(fileName);
    free(colDef);
    free(dirty);

    return 0;
}
